/*
 * @Author: yoola youlikesoilove@qq.com
 * @Date: 2024-12-05 23:20:10
 * @LastEditors: yoola youlikesoilove@qq.com
 * @LastEditTime: 2024-12-30 23:19:25
 * @FilePath: \CrabSystemProject\src\photoFunc\UpdatePhotos.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置:
 * https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include <iostream>
#include <string>
// 需安装 sudo apt-get install libcurl4-openssl-dev
// 验证 pkg-config --modversion libcurl
#include <curl/curl.h>

#ifndef DISABLE_DIRECT_OUTPUT
#include <chrono>
#include <iomanip>
#include <sstream>
#define GET_LOCAL_TIME                                                                                      \
    []() {                                                                                                  \
        auto now = std::chrono::system_clock::now();                                                        \
        auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;     \
        std::time_t t = std::chrono::system_clock::to_time_t(now);                                          \
        std::tm tm = *std::localtime(&t);                                                                   \
        std::ostringstream oss;                                                                             \
        oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S.") << std::setw(3) << std::setfill('0') << ms.count(); \
        return oss.str();                                                                                   \
    }()
#define FILE_LINE   " - " << __FILE__ << "[" << __LINE__ << "] - "
#define OUTPUT_ERRR std::cerr << GET_LOCAL_TIME << FILE_LINE
#define OUPUT_INFO  std::cout << GET_LOCAL_TIME << FILE_LINE
#endif

// Callback function to write response data into a string
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) {
    ((std::string*)userp)->append((char*)contents, size * nmemb);
    return size * nmemb;
}

void uploadFile(
    const std::string& url,
    const std::string& product_id,
    const std::string& api_key,  // Added api_key parameter
    const std::string& device_name,
    const std::string& imei,
    const std::string& file_path) {
    CURL* curl;
    CURLcode res;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if (curl) {
        struct curl_httppost* formpost = nullptr;
        struct curl_httppost* lastptr = nullptr;

        // Add form fields
        curl_formadd(
            &formpost,
            &lastptr,
            CURLFORM_COPYNAME,
            "product_id",
            CURLFORM_COPYCONTENTS,
            product_id.c_str(),
            CURLFORM_END);
        curl_formadd(
            &formpost,
            &lastptr,
            CURLFORM_COPYNAME,
            "device_name",
            CURLFORM_COPYCONTENTS,
            device_name.c_str(),
            CURLFORM_END);

        if (!imei.empty()) {
            curl_formadd(
                &formpost, &lastptr, CURLFORM_COPYNAME, "imei", CURLFORM_COPYCONTENTS, imei.c_str(), CURLFORM_END);
        }

        curl_formadd(&formpost, &lastptr, CURLFORM_COPYNAME, "file", CURLFORM_FILE, file_path.c_str(), CURLFORM_END);

        // Set the URL
        curl_easy_setopt(curl, CURLOPT_URL, url.c_str());

        // Add API_KEY as Authorization header
        struct curl_slist* headers = nullptr;
        std::string auth_header = "Authorization:" + api_key;
        headers = curl_slist_append(headers, auth_header.c_str());
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        // Set the form data
        curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);

        // Capture response into a string
        std::string response;
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

        // Perform the request
        res = curl_easy_perform(curl);

        if (res != CURLE_OK) {
            std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        } else {
            long http_code = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);

            if (http_code == 200) {
                std::cout << "Server response: " << response << std::endl;

                // Check if the response contains "auth failed"
                if (response.find("\"auth failed\"") != std::string::npos) {
                    std::cerr << "Authentication failed: " << response << std::endl;
                } else {
                    std::cout << "File uploaded successfully!" << std::endl;
                }
            } else {
                std::cerr << "HTTP request failed with status code: " << http_code << std::endl;
            }
        }

        // Cleanup
        curl_easy_cleanup(curl);
        curl_formfree(formpost);
        curl_slist_free_all(headers);  // Free the header list
    }

    curl_global_cleanup();
}

// access_key = "J/FpZ/0LP/UjZ9k9Vee7y81Z31dlLSdLhVvZ+9E9kZs=" Z2xGVHZkTFp2UW16MFBleWtxUENUYWxyMG8zUHI3Tkc=
// user_key = "B7MzpK5YwvtQXGx+lRZSvfmuxgkwml/S02Wh0eRpdY2EeAV4x77VTGxENtQYM126LFYqW+qPKJySWTr1ZdetwQ=="

int main() {
    std::string url = "https://iot-api.heclouds.com/device/file-upload";
    std::string api_key =
        "version=2018-10-31&res=products%2F%0A4MLdrQTupB&et=4102329600&method=sha1&sign=GoaEJj90OuW38srTMrqXuoAQxAw%3D";
    std::string product_id = "4MLdrQTupB";
    std::string device_name = "2411169655";
    std::string imei = "undefined";
    std::string file_path = "/home/pi/example_pic/1561517218556.jpg";  // 替换为实际文件路径

    uploadFile(url, product_id, api_key, device_name, imei, file_path);

    return 0;
}
